package com.dempsey.auth.service;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.dempsey.api.RemoteUserService;
import com.dempsey.api.domain.User;
import com.dempsey.api.model.LoginUser;
import com.dempsey.auth.constant.CaptchaConstants;
import com.dempsey.auth.properties.CaptchaProperties;
import com.dempsey.auth.utils.IpUtils;
import com.dempsey.common.core.domain.AjaxResult;
import com.dempsey.common.core.domain.R;
import com.dempsey.common.core.exception.ServiceException;
import com.dempsey.common.core.exception.auth.CaptchaException;
import com.dempsey.common.core.utils.ServletUtils;
import com.dempsey.common.redis.service.RedisService;
import com.dempsey.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;
import org.springframework.util.FastByteArrayOutputStream;

import java.util.concurrent.TimeUnit;

/**
 * 登录校验方法
 *
 * @author Dempsey
 */
@Component
public class SysLoginService {

    private static final Log log = LogFactory.get();

    @Autowired
    private CaptchaProperties captchaProperties;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private RedisService redisService;

    /**
     * 生成验证码
     *
     * @return the ajax result
     */
    public AjaxResult captcha() {
        AjaxResult ajax = AjaxResult.success();
        // 生成验证码对象
        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(120, 40, 4, 4);

        // 将验证码对象缓存到redis中
        String uuid = IdUtil.simpleUUID();
        String verifyKey = CaptchaConstants.CAPTCHA_CODE_KEY + uuid;
        String code = shearCaptcha.getCode();
        redisService.setCacheObject(verifyKey, code, CaptchaConstants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        log.info("生成验证码：{}", code);
        log.info("验证码编号：{}", uuid);
        ajax.put("uuid", uuid);

        //图片转base64输出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        shearCaptcha.write(os);
        String img = Base64Utils.encodeToString(os.toByteArray());
        ajax.put("img", img);

        return ajax;
    }

    /**
     * 登录
     *
     * @param username the username
     * @param password the password
     * @param captcha  the captcha
     * @param uuid     the uuid
     * @return the login user
     */
    public LoginUser login(String username, String password, String captcha, String uuid) {
        // 验证码校验
        boolean captchaOnOff = captchaProperties.getEnabled();
        if (captchaOnOff) {
            checkCaptcha(captcha, uuid);
        }

        // 查询用户信息
        R<User> userResult = remoteUserService.getUserByUsername(username);
        User user = userResult.getData();

        if (null == user) {
            throw new ServiceException("登录用户：" + username + " 不存在");
        }

        if (1 == user.getStatus()) {
            throw new ServiceException("对不起，您的账号：" + username + " 已被删除");
        }

        if (!SecurityUtils.matchesPassword(password, user.getPassword())) {
            throw new ServiceException("用户不存在/密码错误");
        }

        // 查询用户角色信息
        R<String> role = remoteUserService.getUserRoleByUserId(user.getUserId());
        String roleName = role.getData();
        if (null == roleName) {
            throw new ServiceException("登录用户：" + username + " 角色不存在");
        }

        LoginUser loginUser = new LoginUser();
        loginUser.setUser(user);
        loginUser.setRole(roleName);
        loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
        return loginUser;
    }


    private void checkCaptcha(String captcha, String uuid) {
        String verifyKey = CaptchaConstants.CAPTCHA_CODE_KEY + uuid;
        String code = redisService.getCacheObject(verifyKey);
        log.info("校验验证码：输入{}，校验{}", captcha, code);

        if (StrUtil.isEmpty(code)) {
            throw new CaptchaException("验证码已失效");
        }
        if (!StrUtil.equalsIgnoreCase(captcha, code)) {
            throw new CaptchaException("验证码不正确");
        }
    }

    /**
     * 注册
     *
     * @param user    the user
     * @param captcha the captcha
     * @param uuid    the uuid
     */
    public LoginUser register(User user, String captcha, String uuid) {
        // 验证码校验
        boolean captchaOnOff = captchaProperties.getEnabled();
        if (captchaOnOff) {
            checkCaptcha(captcha, uuid);
        }
        R<User> userResult = remoteUserService.createUser(user);
        user = userResult.getData();

        if (null == user) {
            throw new ServiceException("注册用户失败");
        }

        LoginUser loginUser = new LoginUser();
        loginUser.setUser(user);
        // 新建用户必定为普通用户
        loginUser.setRole("普通用户");
        loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));

        return loginUser;
    }

}